package services

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)
type TransactionClosure = func(o orm.Ormer) error

//事务代理
type Transactor struct {
	Num uint32    //事务计数器
	o   orm.Ormer //orm对象
}

func NewTransactor() *Transactor {
	this := &Transactor{
		o: orm.NewOrm(),
	}

	return this
}

//事务闭包
func (this *Transactor) Transaction(f TransactionClosure) error {
	var err error
	if this.Num == 0 {
		if err = this.o.Begin(); err != nil {
			return err
		}
	}
	this.Num++

	//调用逻辑
	if err = f(this.o); err != nil {
		//回滚
		if this.Num > 1 {
			this.Num--
		} else {
			//回滚
			terr := this.o.Rollback()
			if terr != nil {
				beego.Warn("事务回滚异常:" + terr.Error())
			}
		}
		return err
	} else {
		//提交
		if this.Num > 1 {
			this.Num--
		} else {
			//提交
			terr := this.o.Commit()
			if terr != nil {
				beego.Warn("事务提交异常:" + terr.Error())
			}
		}
	}
	return nil
}
